package com.starhub.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

/**
 * 自动扫描并加载properties文件的配置类
 * 动态发现指定目录下的所有properties文件并自动加载
 * 支持黑名单机制排除不需要的配置文件
 */
@Slf4j
@Configuration
public class DynamicPropertiesLoader {

    @Value("${catalina.home:${user.home}}")
    private String catalinaHome;

    private static final String PROPERTIES_DIR = "/conf/starHub/";
    private static final String PROPERTIES_PATTERN = "*.properties";
    
    // 黑名单：这些文件不会被加载
    private static final Set<String> BLACKLIST = new HashSet<>(Arrays.asList(
        "temp.properties",           // 临时配置文件
        "backup.properties",        // 备份配置文件
        "test.properties",          // 测试配置文件
        "debug.properties",         // 调试配置文件
        "local.properties",         // 本地配置文件
        "sample.properties",        // 示例配置文件
        "template.properties"       // 模板配置文件
    ));

    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void autoLoadProperties() {
        try {
            String propertiesPath = catalinaHome + PROPERTIES_DIR;
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            
            // 构建文件路径模式
            String locationPattern = "file:" + propertiesPath + PROPERTIES_PATTERN;
            
            // 获取所有匹配的properties文件
            Resource[] resources = resolver.getResources(locationPattern);
            
            if (resources.length > 0) {
                log.info("=== 开始自动加载properties文件 ===");
                List<String> loadedFiles = new ArrayList<>();
                List<String> skippedFiles = new ArrayList<>();
                
                for (Resource resource : resources) {
                    String filename = resource.getFilename();
                    
                    // 检查是否在黑名单中
                    if (BLACKLIST.contains(filename)) {
                        skippedFiles.add(filename);
                        log.info("  ⏭️  跳过黑名单文件: " + filename);
                        continue;
                    }
                    
                    try {
                        // 尝试加载properties文件
                        ResourcePropertySource propertySource = new ResourcePropertySource(filename, resource);
                        
                        // 将属性添加到Spring环境中
                        if (applicationContext instanceof AnnotationConfigApplicationContext) {
                            // 如果是AnnotationConfigApplicationContext，直接添加
                            ((AnnotationConfigApplicationContext) applicationContext).getEnvironment()
                                .getPropertySources().addLast(propertySource);
                        }
                        
                        loadedFiles.add(filename);
                        log.info("  ✅ 成功加载: " + filename);
                        
                    } catch (Exception e) {
                        log.error("  ❌ 加载失败: " + filename + " - " + e.getMessage());
                    }
                }
                
                log.info("=== 加载结果汇总 ===");
                log.info("成功加载: " + loadedFiles.size() + " 个文件");
                log.info("跳过文件: " + skippedFiles.size() + " 个文件");
                log.info("总文件数: " + resources.length + " 个文件");
                
                if (!loadedFiles.isEmpty()) {
                    log.info("\n已加载的配置文件:");
                    for (String file : loadedFiles) {
                        log.info("  - " + file);
                    }
                }
                
                if (!skippedFiles.isEmpty()) {
                    log.info("\n跳过的配置文件:");
                    for (String file : skippedFiles) {
                        log.info("  - " + file);
                    }
                }
                
                log.info("\n=== 黑名单配置 ===");
                log.info("如需修改黑名单，请编辑 DynamicPropertiesLoader.java 中的 BLACKLIST 集合");
                log.info("当前黑名单文件:");
                for (String blacklistedFile : BLACKLIST) {
                    log.info("  - " + blacklistedFile);
                }
                
            } else {
                log.info("⚠️  警告: 在目录 " + propertiesPath + " 中未找到任何properties文件");
                log.info("请检查目录路径是否正确，或者确认该目录下确实存在.properties文件");
            }
            
        } catch (IOException e) {
            log.error("❌ 扫描properties文件时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 获取当前黑名单列表
     * @return 黑名单文件集合
     */
    public Set<String> getBlacklist() {
        return new HashSet<>(BLACKLIST);
    }
    
    /**
     * 检查文件是否在黑名单中
     * @param filename 文件名
     * @return 是否在黑名单中
     */
    public boolean isBlacklisted(String filename) {
        return BLACKLIST.contains(filename);
    }
    
    /**
     * 添加文件到黑名单（运行时动态添加）
     * @param filename 要添加到黑名单的文件名
     */
    public void addToBlacklist(String filename) {
        BLACKLIST.add(filename);
        log.info("已将 " + filename + " 添加到黑名单");
    }
    
    /**
     * 从黑名单中移除文件（运行时动态移除）
     * @param filename 要从黑名单中移除的文件名
     */
    public void removeFromBlacklist(String filename) {
        if (BLACKLIST.remove(filename)) {
            log.info("已从黑名单中移除 " + filename);
        } else {
            log.info(filename + " 不在黑名单中");
        }
    }
}
